package com.carlinfo.usercenter.common.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;

/**
 * 加密工具类
 * @author wangshMac
 *
 */
public class EncryptUtil
{
	/* 持有一个正则表达式的工具类 */
	private RegexUtil regexUtil = new RegexUtil() ; 
	
	/**
	 * 加密的过程
	 * 
	 * Sha256$随机字母$sha256(随机字母+明文)
	 * 
	 * @param souStr	明文
	 * @return	密文
	 */
	public String encodeStr(String souStr)
	{
		//System.out.println("===encodeStr===");
		String encodeName = "sha256" ; 
		/* 生成一个6位的随机字母+数字(登陆时的验证码) */
		String randStr = this.regexUtil.randString(32);
		/* 随机数+明文 */
		String souEncode = randStr + souStr ; 
		/* 加密后的密码;sha256加密 */
		String encodeStr = DigestUtils.sha256Hex(souEncode);
		
		String result = encodeName + "$" + randStr + "$" + encodeStr  ; 
		return result ; 
	}
	
	/**
	 * 检查明文是否正确
	 * 
	 * Sha256$随机字母$sha256(随机字母+明文)
	 * 拿着明文再按照加密的过程再走一遍,我们比密文是否一样
	 * @return
	 */
	public boolean checkStr(String souStr,String encodeStr)
	{
		/* 如何获取加密算法和随机数
		 * 从加密后的字符串中获取
		 *  */
		/* 先按照$拆分
		 * 参数:是正则表达式,$在正则表达式中有含义;$行的结尾;^:行的开头;
		 * 还想表达原来的含义;
		 *  */
		String[] encodeStrs = encodeStr.split("\\$");
		if(encodeStrs.length != 3)
		{
			return false ; 
		}
		
		//System.out.println("===encodeStr===");
		String encodeName = encodeStrs[0] ; 
		/* 生成一个6位的随机字母+数字(登陆时的验证码) */
		String randStr = encodeStrs[1];
		/* 随机数+明文 */
		String souEncode = randStr + souStr ; 
		/* 加密后的密码;sha256加密 */
		String encodeRes = DigestUtils.sha256Hex(souEncode);
		
		String result = encodeName + "$" + randStr + "$" + encodeRes  ; 
		/*
		 * 判断明文与密文是否匹配
		 * */
		return encodeStr.equalsIgnoreCase(result) ; 
	}
	
	public static void main(String[] args)
	{
		testenc();
		
		EncryptUtil encryptUtil = new EncryptUtil() ; 
		String souStr = "111111";
		/* 加密 */
		String encodeStr = encryptUtil.encodeStr(souStr);
		System.out.println("==encodeStr===" + encodeStr);
		/* 检查结果 */
		boolean flag = encryptUtil.checkStr("222", encodeStr);
		System.out.println("--checkStr-->" + flag);
	}
	
	/**
	 * 测试一些常见的加密算法
	 */
	private static void testenc()
	{
		String souStr = "111111" ;
		/* md5加密
		 * DigestUtils:一定得apache包下面的
		 * 文摘
		 * 
		 * 明文:111111
		 * 密码:96e79218965eb72c92a549dd5a330112
		 * 
		 * Hex是16进制
		 *  */
		String md5Str = DigestUtils.md5Hex(souStr);
		System.out.println("==md5Str==" + md5Str + "--->length:" + md5Str.length());
		
		/* sha256 */
		String sha256Str = DigestUtils.sha256Hex(souStr);
		System.out.println("==sha256Str==" + sha256Str + "--->length:" + sha256Str.length());
		
		/*
		 * sha512
		 * */
		String sha512Str = DigestUtils.sha512Hex(souStr);
		System.out.println("==sha512Str==" + sha512Str + "--->length:" + sha512Str.length());
		
		/* Base64
		 * Base64可以加密,也可以解密
		 *  */
		try
		{
			byte[] souceByte = souStr.getBytes("UTF-8") ; 
			byte[] encodeByte = Base64.encodeBase64(souceByte);
			System.out.println("Base64==souceByte==" + Arrays.toString(souceByte));
			System.out.println("Base64==encodeByte==" + Arrays.toString(encodeByte));
			String encodeStr = new String(encodeByte);
			System.out.println("Base64==encodeStr==" + encodeStr);
			/* 解密 */
			byte[] decodeByte = Base64.decodeBase64(encodeByte);
			System.out.println("Base64==decodeByte==" + Arrays.toString(decodeByte));
			String decodeStr = new String(decodeByte);
			System.out.println("Base64==decodeStr==" + decodeStr);
		} catch (UnsupportedEncodingException e)
		{
			e.printStackTrace();
		}
		
		/* URL加密和解密,不需要codec的包
		 * 只能对url里面的特殊字符加密:如://?&
		 * 如果是非url,无能
		 *  */
		String url = "http://www.baidu.com?id=1&a=10&b=20" ; 
		try
		{
			String encodeUrl = URLEncoder.encode(url,"UTF-8");
			System.out.println("==URLEncoder===" + encodeUrl);
			
			String decodeUrl = URLDecoder.decode(encodeUrl, "UTF-8");
			System.out.println("==decodeUrl===" + decodeUrl);
		} catch (UnsupportedEncodingException e)
		{
			e.printStackTrace();
		}
		
		/* 明文(公钥):key:(参数1)
		 * 盐(私钥):value:(参数2)
		 * hex:16进制
		 * 
		 * 加密参数:公钥大家都知道(客户端和服务器端),并且还在http请求头传输
		 * 盐:不在请求头传输;
		 * 
		 * 返回值:就是加密的字符串
		 *  */
		String key = "111111" ; 
		String value = "test" ; 
		String result = HmacUtils.hmacSha256Hex(key, value);
		System.out.println(key + "==hmacSha256Hex====>" + result);
	}
}
